package com.moodbox.server.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理权限认证异常
     * @param e 权限异常
     * @return 错误响应
     */
    @ExceptionHandler(AuthorizationException.class)
    public ResponseEntity<Map<String, Object>> handleAuthorizationException(AuthorizationException e) {
        log.warn("权限认证异常：{}", e.getMessage());
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "AUTHORIZATION_ERROR");
        errorResponse.put("message", e.getMessage());
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse);
    }

    /**
     * 处理业务异常
     * @param e 业务异常
     * @return 错误响应
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<Map<String, Object>> handleBusinessException(BusinessException e) {
        log.warn("业务异常：{}", e.getMessage());
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "BUSINESS_ERROR");
        errorResponse.put("message", e.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理参数校验异常（@Valid）
     * @param e 参数校验异常
     * @return 错误响应
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, Object>> handleValidationExceptions(MethodArgumentNotValidException e) {
        Map<String, String> errors = e.getBindingResult()
            .getFieldErrors()
            .stream()
            .collect(Collectors.toMap(
                FieldError::getField, 
                fieldError -> fieldError.getDefaultMessage() == null ? "参数校验失败" : fieldError.getDefaultMessage()
            ));

        log.warn("参数校验失败：{}", errors);
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "VALIDATION_ERROR");
        errorResponse.put("message", "参数校验失败");
        errorResponse.put("errors", errors);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理参数校验异常（@Validated）
     * @param e 参数校验异常
     * @return 错误响应
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Map<String, Object>> handleConstraintViolationException(ConstraintViolationException e) {
        Map<String, String> errors = e.getConstraintViolations()
            .stream()
            .collect(Collectors.toMap(
                violation -> violation.getPropertyPath().toString(), 
                violation -> violation.getMessage() == null ? "参数校验失败" : violation.getMessage()
            ));

        log.warn("参数校验失败：{}", errors);
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "VALIDATION_ERROR");
        errorResponse.put("message", "参数校验失败");
        errorResponse.put("errors", errors);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理敏感词相关异常
     * @param e 敏感词异常
     * @return 错误响应
     */
    @ExceptionHandler(SensitiveWordException.class)
    public ResponseEntity<Map<String, Object>> handleSensitiveWordException(SensitiveWordException e) {
        log.warn("敏感词处理异常：{}", e.getMessage());
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "SENSITIVE_WORD_ERROR");
        errorResponse.put("message", e.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理文件上传大小超限异常
     * @param e 文件上传异常
     * @return 错误响应
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<Map<String, Object>> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.warn("文件上传大小超限：{}", e.getMessage());
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "FILE_UPLOAD_SIZE_EXCEEDED");
        errorResponse.put("message", "上传文件大小超过限制");
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理通用异常
     * @param e 未知异常
     * @return 错误响应
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception e) {
        log.error("未知异常：", e);
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", "INTERNAL_SERVER_ERROR");
        errorResponse.put("message", "服务器发生未知错误");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
} 